# 导入必要的模块
import socket  # 用于UDP网络通信，提供网络套接字编程接口
import keyboard  # 用于监听键盘事件，捕获用户的按键输入
import sys  # 用于程序退出控制，提供系统级功能

# UDP网络配置
TARGET_IP = '192.168.4.1'  # ESP32/ESP8266的IP地址（需要根据实际情况修改）
TARGET_PORT = 8888  # 目标端口号，与接收端保持一致

# 创建UDP套接字
# AF_INET表示使用IPv4协议，SOCK_DGRAM表示使用UDP协议
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

def on_key_press(event):
    '''
    键盘事件处理函数
    参数：
        event: keyboard.KeyboardEvent对象
            包含按键事件的详细信息，如按键名称、事件类型等
    功能：
        1. 检测按键按下事件
        2. 通过UDP发送按键信息到目标设备
        3. 处理ESC键的程序退出功能
    '''
    if event.event_type == keyboard.KEY_DOWN:  # 只处理按键按下事件，忽略按键释放
        key_name = event.name  # 获取按键名称（如'w', 'a', 's', 'd'等）
        try:
            # 发送按键信息到目标地址
            # encode()将字符串转换为字节序列，便于网络传输
            sock.sendto(key_name.encode(), (TARGET_IP, TARGET_PORT))
            print(f'发送按键：{key_name}')
        except Exception as e:
            # 捕获并打印所有可能的网络发送错误
            print(f'发送错误：{str(e)}')
        
        # ESC键用于优雅退出程序
        if key_name == 'esc':
            print('程序退出')
            keyboard.unhook_all()  # 取消所有按键监听，清理资源
            sock.close()  # 关闭UDP套接字连接
            sys.exit(0)  # 正常退出程序，返回状态码0

if __name__ == '__main__':
    # 程序启动时的提示信息
    print('WiFi UDP键盘发送程序已启动')
    print(f'目标IP地址：{TARGET_IP}')
    print('按ESC键退出程序')
    
    # 注册键盘事件监听器，将on_key_press函数注册为回调函数
    keyboard.hook(on_key_press)
    
    # 保持程序运行，直到按下ESC键
    # keyboard.wait()会阻塞程序执行，等待键盘事件
    keyboard.wait()